package passworks;

import java.util.ArrayList;
import java.util.List;

public abstract class GateBase {

    protected List<Wire> input;
    protected List<Wire> output;
    protected int iterations;
    //private int ID;  Nem szabad ID-t, meg...

    /*
     * Ez azert kell, hogy tudjuk, hogy feltetelezni kell-e a kapuk bemeneteinek logikai erteket.
     */
    public static boolean checkStable = true;

    /*
     * Szkeleton miatt kell
     */
    protected String className;
    protected int ownID;

    public GateBase() {
        input = new ArrayList<Wire>();
        output = new ArrayList<Wire>();

        iterations = 0;
    }

    public void AddInput(Wire w) {
        Logger.Print(className, "AddInput", Direction.IN, ownID);
        input.add(w);
        Logger.Print(className, "AddInput", Direction.OUT, ownID);
    }

    public void AddOutput(Wire w) {
        Logger.Print(className, "AddOutput", Direction.IN, ownID);
        output.add(w);
        Logger.Print(className, "AddOutput", Direction.OUT, ownID);
    }

    public void Handle(List<GateBase> actGates) {
        Logger.Print(className, "Handle", Direction.IN, ownID);

        /*
         * Flag arra, hogy a bemenetre feltetelezzen-e stabil vezeteket
         */
        boolean onList = (actGates.indexOf(this) != -1);

        /*
         * Leveszi magat, ha rajta van
         */
        if (onList) {
            actGates.remove(this);
            Logger.Print("actGates", "remove", Direction.SINGLE, -1);
        }

        /*
         * checkStable - megnezi, hogy stabilak-e a bemenetek
         */
        if (checkStable) {
            for (Wire w : input) {
                /*
                 * Ha talal egy nem stabil bemenetet azonnal kilep
                 */
                if (!w.GetStable()) {
                    actGates.add(this);
                    Logger.Print("actGates", "add", Direction.SINGLE, -1);
                    Logger.Print(className, "Handle", Direction.OUT, ownID);
                    return;
                }
            }
            /*
             * Ha minden stabil nem kell foglalkozni a kimenetek megvaltozasaval
             */
            this.SetOutputs();

            /*
             * Minden kimenetre meghivjuk a Handle-t
             */
            for (Wire w : output) {
                w.GetGate().Handle(actGates);
            }
        } else {
//            List<Boolean> currentOutputs = new ArrayList<Boolean>();
//            for (Wire w : output) {
//                currentOutputs.add(w.GetState());
//            }

            this.SetOutputs();
            if(Logger.Read("Valtozott a kapu kimenete?")) {
                /*
                 * Minden kimenetre ujra meghivjuk a Handle-t
                 */
                for (Wire w : output) {
                    w.GetGate().Handle(actGates);
                }
            }
//          iterations++;
//            for (int i = 0; i < output.size(); ++i) {
//                if(output.get(i).GetState() != currentOutputs.get(i)){
//
//                }
//            }
        }

        Logger.Print(className, "Handle", Direction.OUT, ownID);
    }

    public int GetIterations() {
        Logger.Print(className, "GetIterations", Direction.IN, ownID);
        Logger.Print(className, "GetIterations", Direction.OUT, ownID);
        return 0;
    }

    // Absztrakt fv-ek, minden kapura kulon implementalni
    public abstract void SetOutputs();

    public abstract void Init();
}
